import { Cube } from '@/assets/basesrc/cube';

/**
 * {@link Cube}.
 */

/** Creates a new instance. */
var RubiksCube = function () {
    this.init(3);
    this.partSize = 1.78;
    var partSize = this.partSize;
    this.cornerScale = [
      [0.8, 0.8, 1.2],
      [1.2, 1.2, 0.8],
      [1.2, 0.8, 1.2],
      [1.2, 1.2, 1.2],
      [1.2, 0.8, 0.8],
      [0.8, 1.2, 1.2],
      [0.8, 0.8, 0.8],
      [0.8, 1.2, 0.8]
    ];
    this.cornetTranslate = [
      [-partSize * 0.15, partSize * 0.15, partSize * 0.05],
      [partSize * 0.05, -partSize * 0.05, -partSize * 0.15],
      [partSize * 0.05, partSize * 0.15, partSize * 0.05],
      [partSize * 0.05, -partSize * 0.05, partSize * 0.05],
      [partSize * 0.05, partSize * 0.15, -partSize * 0.15],
      [-partSize * 0.15, -partSize * 0.05, partSize * 0.05],
      [-partSize * 0.15, partSize * 0.15, -partSize * 0.15],
      [-partSize * 0.15, -partSize * 0.05, -partSize * 0.15]
    ];
    this.edgeScale=[
        [1, 1.2, 0.8],
        [1, 0.8, 1.2],
        [1, 1.2, 1.2],
        [1, 0.8, 1.2],
        [1, 1.2, 1.2],
        [1, 1.2, 1.2],
        [1, 0.8, 0.8],
        [1, 1.2, 0.8],
        [1, 0.8, 1.2],
        [1, 0.8, 0.8],
        [1, 0.8, 0.8],
        [1, 1.2, 0.8]
    ];
    this.edgeTranslate=[
[0, -partSize * 0.05, -partSize * 0.15],
[0, partSize * 0.15, partSize * 0.05],
[0, -partSize * 0.05, partSize * 0.05],
[0, partSize * 0.15, partSize * 0.05],
[0, -partSize * 0.05, partSize * 0.05],
[0, -partSize * 0.05, partSize * 0.05],
[0, partSize * 0.15, -partSize * 0.15],
[0, -partSize * 0.05, -partSize * 0.15],
[0, partSize * 0.15, partSize * 0.05],
[0, partSize * 0.15, -partSize * 0.15],
[0, partSize * 0.15, -partSize * 0.15],
[0, -partSize * 0.05, -partSize * 0.15]
    ];
    this.sideScale=[

    ];
    this.sideTranslate=[

    ];
}

RubiksCube.prototype = new Cube();
/**
 * Set this variable to true to get debug output when the cube is transformed.
 */
RubiksCube.prototype.DEBUG = false;
/**
 * Holds the number of face parts, which is 6.
 */
RubiksCube.prototype.NUMBER_OF_SIDE_PARTS = 6;
/**
 * Holds the number of edge parts, which is 12.
 */
RubiksCube.prototype.NUMBER_OF_EDGE_PARTS = 12;
/**
 * This is used for mapping face part locations
 * to/from sticker positions on the cube.
 *
 * @see #toStickers
 */
RubiksCube.prototype.SIDE_TRANSLATION = [
    [0, 4],
    [1, 4],
    [2, 4],
    [3, 4],
    [4, 4],
    [5, 4]
];
/**
 * @see #toStickers
 */
RubiksCube.prototype.EDGE_TRANSLATION = [
    [1, 5, 0, 1], // edge 0 ur
    [0, 3, 2, 5], //      1 rf
    [4, 5, 0, 7], //      2 dr
    [5, 1, 1, 1], //      3 bu
    [0, 5, 5, 3], //      4 rb
    [5, 7, 4, 7], //      5 bd
    [1, 3, 3, 1], //      6 ul
    [3, 3, 5, 5], //      7 lb
    [4, 3, 3, 7], //      8 dl
    [2, 1, 1, 7], //      9 fu
    [3, 5, 2, 3], //     10 lf
    [2, 7, 4, 1] //     11 fd
];
/**
 * @see #toStickers
 */
RubiksCube.prototype.CORNER_TRANSLATION = [
    [1, 8, 0, 0, 2, 2], // 0 urf 
    [4, 2, 2, 8, 0, 6], // 1 dfr
    [1, 2, 5, 0, 0, 2], // 2 ubr
    [4, 8, 0, 8, 5, 6], // 3 drb
    [1, 0, 3, 0, 5, 2], // 4 ulb
    [4, 6, 5, 8, 3, 6], // 5 dbl
    [1, 6, 2, 0, 3, 2], // 6 ufl
    [4, 0, 3, 8, 2, 6] // 7 dlf
];
RubiksCube.prototype.EDGE_SWIPE_TABLE = [
    [ // edge 0 ur
        [//u
            [2, 2, 1], // axis, layerMask, angle
            [0, 4, -1],
            [2, 2, -1],
            [0, 4, 1]
        ],
        [//r
            [2, 2, -1], // axis, layerMask, angle
            [1, 4, -1],
            [2, 2, 1],
            [1, 4, 1]
        ],],
    [ //      1 rf
        [//r
            [1, 2, 1], // axis, layerMask, angle
            [2, 4, -1],
            [1, 2, -1],
            [2, 4, 1]
        ],
        [//f
            [1, 2, -1], // axis, layerMask, angle
            [0, 4, -1],
            [1, 2, 1],
            [0, 4, 1]
        ],],
    [ //      2 dr
        [//d
            [2, 2, -1], // axis, layerMask, angle
            [0, 4, -1],
            [2, 2, 1],
            [0, 4, 1]
        ],
        [//r
            [2, 2, 1], // axis, layerMask, angle
            [1, 1, 1],
            [2, 2, -1],
            [1, 1, -1]
        ],],
    [ //      3 bu
        [//b
            [0, 2, -1], // axis, layerMask, angle
            [1, 4, -1],
            [0, 2, 1],
            [1, 4, 1]
        ],
        [//u
            [0, 2, 1], // axis, layerMask, angle
            [2, 1, 1],
            [0, 2, -1],
            [2, 1, -1]
        ],],
    [ //      4 rb
        [//r
            [1, 2, -1], // axis, layerMask, angle
            [2, 1, 1],
            [1, 2, 1],
            [2, 1, -1]
        ],
        [//b
            [1, 2, 1], // axis, layerMask, angle
            [0, 4, -1],
            [1, 2, -1],
            [0, 4, 1]
        ],],
    [ //      5 bd
        [//b
            [0, 2, 1], // axis, layerMask, angle
            [1, 1, 1],
            [0, 2, -1],
            [1, 1, -1]
        ],
        [//d
            [0, 2, -1], // axis, layerMask, angle
            [2, 1, 1],
            [0, 2, 1],
            [2, 1, -1]
        ],],
    [ //      6 ul
        [//u
            [2, 2, -1], // axis, layerMask, angle
            [0, 1, 1],
            [2, 2, 1],
            [0, 1, -1]
        ],
        [//l
            [2, 2, 1], // axis, layerMask, angle
            [1, 4, -1],
            [2, 2, -1],
            [1, 4, 1]
        ],],
    [ //      7 lb
        [//l
            [1, 2, 1], // axis, layerMask, angle
            [2, 1, 1],
            [1, 2, -1],
            [2, 1, -1]
        ],
        [//b
            [1, 2, -1], // axis, layerMask, angle
            [0, 1, 1],
            [1, 2, 1],
            [0, 1, -1]
        ],],
    [ //      8 dl
        [//d
            [2, 2, 1], // axis, layerMask, angle
            [0, 1, 1],
            [2, 2, -1],
            [0, 1, -1]
        ],
        [//l
            [2, 2, -1], // axis, layerMask, angle
            [1, 1, 1],
            [2, 2, 1],
            [1, 1, -1]
        ],],
    [ //      9 fu
        [//f
            [0, 2, 1], // axis, layerMask, angle
            [1, 4, -1],
            [0, 2, -1],
            [1, 4, 1]
        ],
        [//u
            [0, 2, -1], // axis, layerMask, angle
            [2, 4, -1],
            [0, 2, 1],
            [2, 4, 1]
        ],],
    [ //     10 lf
        [//l
            [1, 2, -1], // axis, layerMask, angle
            [2, 4, -1],
            [1, 2, 1],
            [2, 4, 1]
        ],
        [//f
            [1, 2, 1], // axis, layerMask, angle
            [0, 1, 1],
            [1, 2, -1],
            [0, 1, -1]
        ],],
    [ //     11 fd
        [//f
            [0, 2, -1], // axis, layerMask, angle
            [1, 1, 1],
            [0, 2, 1],
            [1, 1, -1]
        ],
        [//d
            [0, 2, 1], // axis, layerMask, angle
            [2, 4, -1],
            [0, 2, -1],
            [2, 4, 1]
        ],]
];
RubiksCube.prototype.SIDE_SWIPE_TABLE = [
    [// 0 r
        [1, 2, -1], // axis, layerMask, angle
        [2, 2, 1],
        [1, 2, 1],
        [2, 2, -1]
    ],
    [// 1 u
        [2, 2, -1],
        [0, 2, 1],
        [2, 2, 1],
        [0, 2, -1]
    ],
    [// 2 f
        [0, 2, -1],
        [1, 2, 1],
        [0, 2, 1],
        [1, 2, -1]
    ],
    [// 3 l
        [2, 2, 1],
        [1, 2, -1],
        [2, 2, -1],
        [1, 2, 1]
    ],
    [// 4 d
        [0, 2, 1],
        [2, 2, -1],
        [0, 2, -1],
        [2, 2, 1]
    ],
    [ // 5 b
        [1, 2, 1],
        [0, 2, -1],
        [1, 2, -1],
        [0, 2, 1]
    ]
];


/**
 * Returns the current layer mask on which the orientation of the part lies.
 * Returns 0 if no mask can be determined (the center part).
 */
RubiksCube.prototype.getPartLayerMask = function (part, orientation) {
    var face = this.getPartFace(part, orientation);
    if (part < this.this.cornerLoc.length) {
        return (face < 3) ? 4 : 1;
    } else if (part < this.this.cornerLoc.length + this.this.edgeLoc.length) {
        return 2;
    } else if (part < this.this.cornerLoc.length + this.this.edgeLoc.length + this.this.sideLoc.length) {
        return (face < 3) ? 4 : 1;
    } else {
        return 0;
    }

}

RubiksCube.prototype.getPartSwipeAxis = function (part, orientation, swipeDirection) {
    if (part < this.cornerLoc.length) {
        var loc = this.getCornerLocation(part);
        var ori = (3 - this.getPartOrientation(part) + orientation) % 3;
        return this.CORNER_SWIPE_TABLE[loc][ori][swipeDirection][0];
    } else if (part < this.cornerLoc.length + this.edgeLoc.length) {
        // Edge parts
        var edgeIndex = part - this.cornerLoc.length;
        var loc = this.getEdgeLocation(edgeIndex);
        var ori = (2 - this.getPartOrientation(part) + orientation) % 2;
        return this.EDGE_SWIPE_TABLE[loc][ori][swipeDirection][0];
    } else if (part < this.cornerLoc.length + this.edgeLoc.length + this.sideLoc.length) {
        var loc = this.getSideLocation(part - this.cornerLoc.length - this.edgeLoc.length);
        var ori = (4 - this.getPartOrientation(part) + swipeDirection) % 4;
        return this.SIDE_SWIPE_TABLE[loc][ori][0];
    } else {
        return -1;
    }

}

RubiksCube.prototype.getPartSwipeLayerMask = function (part, orientation, swipeDirection) {
    if (part < this.cornerLoc.length) {
        var loc = this.getCornerLocation(part);
        var ori = (3 - this.getPartOrientation(part) + orientation) % 3;
        return this.CORNER_SWIPE_TABLE[loc][ori][swipeDirection][1];
    } else if (part < this.cornerLoc.length + this.edgeLoc.length) {
        var edgeIndex = part - this.cornerLoc.length;
        var loc = this.getEdgeLocation(edgeIndex);
        var ori = (2 - this.getPartOrientation(part) + orientation) % 2;
        return this.EDGE_SWIPE_TABLE[loc][ori][swipeDirection][1];
    } else if (part < this.cornerLoc.length + this.edgeLoc.length + this.sideLoc.length) {
        var loc = this.getSideLocation(part - this.cornerLoc.length - this.edgeLoc.length);
        var ori = (4 - this.getPartOrientation(part) + swipeDirection) % 4;
        return this.SIDE_SWIPE_TABLE[loc][ori][1];
    } else {
        return 0;
    }

}

RubiksCube.prototype.getPartSwipeAngle = function (part, orientation, swipeDirection) {
    if (part < this.cornerLoc.length) {
        var loc = this.getCornerLocation(part);
        var ori = this.getPartOrientation(part);
        var sori = (3 - ori + orientation) % 3;
        var dir = swipeDirection;
        var angle = this.CORNER_SWIPE_TABLE[loc][sori][dir][2];
        if (ori == 2 && (sori == 0 || sori == 2)) {
            angle = -angle;
        } else if (ori == 1 && (sori == 1 || sori == 2)) {
            angle = -angle;
        }
        return angle;
    } else if (part < this.cornerLoc.length + this.edgeLoc.length) {
        var edgeIndex = part - this.cornerLoc.length;
        var loc = this.getEdgeLocation(edgeIndex);
        var ori = this.getEdgeOrientation(edgeIndex);
        var sori = (2 - ori + orientation) % 2;
        var dir = swipeDirection;
        var angle = this.EDGE_SWIPE_TABLE[loc][sori][dir][2];
        return angle;
    } else if (part < this.cornerLoc.length + this.edgeLoc.length + this.sideLoc.length) {
        var loc = this.getSideLocation(part - this.cornerLoc.length - this.edgeLoc.length);
        var ori = (4 - this.getPartOrientation(part) + swipeDirection) % 4;
        return this.SIDE_SWIPE_TABLE[loc][ori][2];
    } else {
        return 0;
    }

}

/**
 * Transforms the cube and fires a cubeTwisted event.
 * @param  axis  0=x, 1=y, 2=z axis.
 * @param  layerMask A bitmask specifying the layers to be transformed.
 * @param  angle  positive values=clockwise rotation<br>
 */
RubiksCube.prototype.transform0 = function (axis, layerMask, angle) {
    // var swap=this.cornerLoc[0];
    // this.cornerLoc[0]=this.cornerLoc[1];
    // this.cornerLoc[1]=this.cornerLoc[7];
    // this.cornerLoc[7]=this.cornerLoc[6];
    // this.cornerLoc[1]=swap
    if (this.DEBUG) {
        window.console.log("RubiksCube#" + (this) + ".transform(ax=" + axis + ",msk=" + layerMask + ",ang:" + angle + ")");
    } else if (true) {
        if (axis < 0 || axis > 2) {
            throw ("axis: " + axis);
        }

        if (layerMask < 0 || layerMask >= 1 << this.layerCount) {
            throw ("layerMask: " + layerMask);
        }

        if (angle < -2 || angle > 2) {
            throw ("angle: " + angle);
        }

        if (angle == 0) {
            return; // NOP
        }

        // Convert angle -2 to 2 to simplify the switch statements
        var an = (angle == -2) ? 2 : angle;

        if ((layerMask & 1) != 0) {
            // twist at left, bottom, back
            switch (axis) {
                case 0: // x
                    switch (an) {
                        case -1:
                            this.twistL();
                            break;
                        case 1:
                            this.twistL();
                            this.twistL();
                            this.twistL();
                            break;
                        case 2:
                            this.twistL();
                            this.twistL();
                            break;
                    }
                    break;
                case 1: // y
                    switch (an) {
                        case -1:
                            this.twistD();
                            break;
                        case 1:
                            this.twistD();
                            this.twistD();
                            this.twistD();
                            break;
                        case 2:
                            this.twistD();
                            this.twistD();
                            break;
                    }
                    break;
                case 2: // z
                    switch (an) {
                        case -1:
                            this.twistB();
                            break;
                        case 1:
                            this.twistB();
                            this.twistB();
                            this.twistB();
                            break;
                        case 2:
                            this.twistB();
                            this.twistB();
                            break;
                    }
            }
        }
        if ((layerMask & 2) != 0) {
            // twist at left middle, bottom middle, back middle
            switch (axis) {
                case 0: // x
                    switch (an) {
                        case 1:
                            this.twistMR();
                            break;
                        case -1:
                            this.twistMR();
                            this.twistMR();
                            this.twistMR();
                            break;
                        case 2:
                            this.twistMR();
                            this.twistMR();
                            break;
                    }
                    break;
                case 1: // y
                    switch (an) {
                        case 1:
                            this.twistMU();
                            break;
                        case -1:
                            this.twistMU();
                            this.twistMU();
                            this.twistMU();
                            break;
                        case 2:
                            this.twistMU();
                            this.twistMU();
                            break;
                    }
                    break;
                case 2: // z
                    switch (an) {
                        case 1:
                            this.twistMF();
                            break;
                        case -1:
                            this.twistMF();
                            this.twistMF();
                            this.twistMF();
                            break;
                        case 2:
                            this.twistMF();
                            this.twistMF();
                            break;
                    }
            }
        }

        if ((layerMask & 4) != 0) {

            // twist at right, top, front
            switch (axis) {
                case 0: // x
                    switch (an) {
                        case 1:
                            this.twistR();
                            break;
                        case -1:
                            this.twistR();
                            this.twistR();
                            this.twistR();
                            break;
                        case 2:
                            this.twistR();
                            this.twistR();
                            break;
                    }
                    break;
                case 1: // y
                    switch (an) {
                        case 1:
                            this.twistU();
                            break;
                        case -1:
                            this.twistU();
                            this.twistU();
                            this.twistU();
                            break;
                        case 2:
                            this.twistU();
                            this.twistU();
                            break;
                    }
                    break;
                case 2: // z
                    switch (an) {
                        case 1:
                            this.twistF();
                            break;
                        case -1:
                            this.twistF();
                            this.twistF();
                            this.twistF();
                            break;
                        case 2:
                            this.twistF();
                            this.twistF();
                            break;
                    }
            }
        }
    }
}

RubiksCube.prototype.twistR = function () {
    this.fourCycle(this.cornerLoc, 0, 1, 3, 2, this.cornerOrient, 1, 2, 1, 2, 3);
    this.fourCycle(this.edgeLoc, 0, 1, 2, 4, this.edgeOrient, 1, 1, 1, 1, 2);
    this.sideOrient[0] = (this.sideOrient[0] + 3) % 4;
}

RubiksCube.prototype.twistU = function () {
    this.fourCycle(this.cornerLoc, 0, 2, 4, 6, this.cornerOrient, 0, 0, 0, 0, 3);
    this.fourCycle(this.edgeLoc, 0, 3, 6, 9, this.edgeOrient, 1, 1, 1, 1, 2);
    this.sideOrient[1] = (this.sideOrient[1] + 3) % 4;
}

RubiksCube.prototype.twistF = function () {
    this.fourCycle(this.cornerLoc, 6, 7, 1, 0, this.cornerOrient, 1, 2, 1, 2, 3);
    this.fourCycle(this.edgeLoc, 9, 10, 11, 1, this.edgeOrient, 1, 1, 1, 1, 2);
    this.sideOrient[2] = (this.sideOrient[2] + 3) % 4;
}

RubiksCube.prototype.twistL = function () {
    this.fourCycle(this.cornerLoc, 6, 4, 5, 7, this.cornerOrient, 2, 1, 2, 1, 3);
    this.fourCycle(this.edgeLoc, 6, 7, 8, 10, this.edgeOrient, 1, 1, 1, 1, 2);
    this.sideOrient[3] = (this.sideOrient[3] + 3) % 4;
}

RubiksCube.prototype.twistD = function () {
    this.fourCycle(this.cornerLoc, 7, 5, 3, 1, this.cornerOrient, 0, 0, 0, 0, 3);
    this.fourCycle(this.edgeLoc, 2, 11, 8, 5, this.edgeOrient, 1, 1, 1, 1, 2);
    this.sideOrient[4] = (this.sideOrient[4] + 3) % 4;
}

RubiksCube.prototype.twistB = function () {
    this.fourCycle(this.cornerLoc, 2, 3, 5, 4, this.cornerOrient, 1, 2, 1, 2, 3);
    this.fourCycle(this.edgeLoc, 3, 4, 5, 7, this.edgeOrient, 1, 1, 1, 1, 2);
    this.sideOrient[5] = (this.sideOrient[5] + 3) % 4;
}

RubiksCube.prototype.twistMR = function () {
    this.fourCycle(this.edgeLoc, 3, 9, 11, 5, this.edgeOrient, 1, 1, 1, 1, 2);
    this.fourCycle(this.sideLoc, 2, 4, 5, 1, this.sideOrient, 2, 3, 2, 1, 4);
}

RubiksCube.prototype.twistMU = function () {
    this.fourCycle(this.edgeLoc, 1, 4, 7, 10, this.edgeOrient, 1, 1, 1, 1, 2);
    this.fourCycle(this.sideLoc, 3, 2, 0, 5, this.sideOrient, 2, 1, 2, 3, 4);
}

RubiksCube.prototype.twistMF = function () {
    this.fourCycle(this.edgeLoc, 0, 6, 8, 2, this.edgeOrient, 1, 1, 1, 1, 2);
    this.fourCycle(this.sideLoc, 0, 1, 3, 4, this.sideOrient, 1, 2, 3, 2, 4);
}

/**
 *             +---+---+---+
 *             |1,0|1,1|1,2|
 *             +--- --- ---+
 *             |1,3|1,4|1,5|
 *             +--- --- ---+
 *             |1,6|1,7|1,8|
 * +---+---+---+---+---+---+---+---+---+---+---+---+
 * |3,0|3,1|3,2|2,0|2,1|2,2|0,0|0,1|0,2|5,0|5,1|5,2|
 * +--- --- ---+--- --- ---+--- --- ---+--- --- ---+
 * |3,3|3,4|3,5|2,3|2,4|2,5|0,3|0,4|0,5|5,3|5,4|5,5|
 * +--- --- ---+--- --- ---+--- --- ---+--- --- ---+
 * |3,6|3,7|3,8|2,6|2,7|2,8|0,0|0,1|0,2|5,0|5,1|5,2|
 * +---+---+---+---+---+---+---+---+---+---+---+---+
 *             |4,0|4,1|4,2|
 *             +--- --- ---+
 *             |4,3|4,4|4,5|
 *             +--- --- ---+
 *             |4,6|4,7|4,8|
 *             +---+---+---+
 * @return A two dimensional array. First dimension: faces.
 */
RubiksCube.prototype.toStickers = function () {
    var stickers = new Array(6);
    for (var i = 0; i < 6; i++) {
        stickers[i] = new Array(9);
    }

    // Map face parts onto stickers.
    for (var i = 0; i
        < 6; i++) {
        var loc = this.sideLoc[i];
        stickers[this.SIDE_TRANSLATION[i][0]][this.SIDE_TRANSLATION[i][1]] = this.SIDE_TRANSLATION[loc][0];
    }

    // Map edge parts onto stickers
    for (var i = 0; i
        < 12; i++) {
        var loc = this.edgeLoc[i];
        var orient = this.edgeOrient[i];
        stickers[this.EDGE_TRANSLATION[i][0]][this.EDGE_TRANSLATION[i][1]] =
            (orient == 0) ? this.EDGE_TRANSLATION[loc][0] : this.EDGE_TRANSLATION[loc][2];
        stickers[this.EDGE_TRANSLATION[i][2]][this.EDGE_TRANSLATION[i][3]] =
            (orient == 0) ? this.EDGE_TRANSLATION[loc][2] : this.EDGE_TRANSLATION[loc][0];
    }

    // Map corner parts onto stickers
    for (var i = 0; i
        < 8; i++) {
        var loc = this.cornerLoc[i];
        var orient = this.cornerOrient[i];
        stickers[this.CORNER_TRANSLATION[i][0]][this.CORNER_TRANSLATION[i][1]] =
            (orient == 0)
                ? this.CORNER_TRANSLATION[loc][0]
                : ((orient == 1)
                    ? this.CORNER_TRANSLATION[loc][2]
                    : this.CORNER_TRANSLATION[loc][4]);
        stickers[this.CORNER_TRANSLATION[i][2]][this.CORNER_TRANSLATION[i][3]] =
            (orient == 0)
                ? this.CORNER_TRANSLATION[loc][2]
                : ((orient == 1)
                    ? this.CORNER_TRANSLATION[loc][4]
                    : this.CORNER_TRANSLATION[loc][0]);
        stickers[this.CORNER_TRANSLATION[i][4]][this.CORNER_TRANSLATION[i][5]] =
            (orient == 0)
                ? this.CORNER_TRANSLATION[loc][4]
                : ((orient == 1)
                    ? this.CORNER_TRANSLATION[loc][0]
                    : this.CORNER_TRANSLATION[loc][2]);
    }
    /*
    for (var i = 0; i < stickers.length; i++) {
    System.out.prvar("  " + i + ":");
    for (var j = 0; j < stickers[i].length; j++) {
    if (j != 0) {
    System.out.prvar(',');
    }
    System.out.prvar(stickers[i][j]);
    }
    window.console.log();
    }*/

    return stickers;
}

/**
 * @see #toStickers
 * @param stickers An array of dimensions [6][9] containing sticker values
 */
RubiksCube.prototype.setToStickers = function (stickers) {
    var i = 0, j = 0, cube;

    var tempSideLoc = new Array(6);
    var tempSideOrient = new Array(6);
    var tempEdgeLoc = new Array(12);
    var tempEdgeOrient = new Array(12);
    var tempCornerLoc = new Array(8);
    var tempCornerOrient = new Array(8);

    // Translate face cubes to match stickers.
    try {
        for (i = 0; i
            < 6; i++) {
            for (j = 0; j
                < 6; j++) {
                if (this.SIDE_TRANSLATION[j][0] == stickers[i][this.SIDE_TRANSLATION[j][1]]) {
                    tempSideLoc[i] = this.SIDE_TRANSLATION[j][0];
                    break;
                }
            }
            //this.sideOrient[i] = 0; // already done by reset
        }
    } catch (e) {
        throw ("Invalid side cube " + i);
    }

    for (i = 0; i
        < 5; i++) {
        for (j = i + 1; j
            < 6; j++) {
            if (tempSideLoc[i] == tempSideLoc[j]) {
                throw ("Duplicate side cubes " + i + "+" + j);
            }
        }
    }
    // Translate edge cubes to match stickers.
    for (i = 0; i
        < 12; i++) {
        var f0 = stickers[this.EDGE_TRANSLATION[i][0]][this.EDGE_TRANSLATION[i][1]];
        var f1 = stickers[this.EDGE_TRANSLATION[i][2]][this.EDGE_TRANSLATION[i][3]];
        for (cube = 0; cube
            < 12; cube++) {
            if (this.EDGE_TRANSLATION[cube][0] == f0
                && this.EDGE_TRANSLATION[cube][2] == f1) {
                tempEdgeOrient[i] = 0; //??
                break;

            } else if (this.EDGE_TRANSLATION[cube][0] == f1
                && this.EDGE_TRANSLATION[cube][2] == f0) {
                tempEdgeOrient[i] = 1;
                break;
            }
        }
        if (cube == 12) {
            throw ("Invalid edge cube " + i);
        }

        tempEdgeLoc[i] = cube;
    }

    for (i = 0; i
        < 11; i++) {
        for (j = i + 1; j
            < 12; j++) {
            if (tempEdgeLoc[i] == tempEdgeLoc[j]) {
                throw new IllegalArgumentException(
                    "Duplicate edge cubes tempEdgeLoc[" + i + "]=" + tempEdgeLoc[i] + " tempEdgeLoc[" + j + "]=" + tempEdgeLoc[j]);
            }
        }
    }

    // Translate corner cubes to match stickers.
    for (i = 0; i
        < 8; i++) {
        var f0 = stickers[this.CORNER_TRANSLATION[i][0]][this.CORNER_TRANSLATION[i][1]];
        var f1 = stickers[this.CORNER_TRANSLATION[i][2]][this.CORNER_TRANSLATION[i][3]];
        var f2 = stickers[this.CORNER_TRANSLATION[i][4]][this.CORNER_TRANSLATION[i][5]];
        for (cube = 0; cube
            < 8; cube++) {
            if (this.CORNER_TRANSLATION[cube][0] == f0
                && this.CORNER_TRANSLATION[cube][2] == f1
                && this.CORNER_TRANSLATION[cube][4] == f2) {
                tempCornerOrient[i] = 0;
                break;

            } else if (this.CORNER_TRANSLATION[cube][0] == f2
                && this.CORNER_TRANSLATION[cube][2] == f0
                && this.CORNER_TRANSLATION[cube][4] == f1) {
                tempCornerOrient[i] = 1;
                break;

            } else if (this.CORNER_TRANSLATION[cube][0] == f1
                && this.CORNER_TRANSLATION[cube][2] == f2
                && this.CORNER_TRANSLATION[cube][4] == f0) {
                tempCornerOrient[i] = 2;
                break;
            }
        }
        if (cube == 8) {
            throw new IllegalArgumentException("Invalid corner cube " + i);
        }
        tempCornerLoc[i] = cube;
    }

    for (i = 0; i
        < 7; i++) {
        for (j = i + 1; j
            < 8; j++) {
            if (tempCornerLoc[i] == tempCornerLoc[j]) {
                throw new IllegalArgumentException(
                    "Duplicate corner cubes tempCornerLoc[" + i + "]=" + tempCornerLoc[i] + " tempCornerLoc[" + j + "]=" + tempCornerLoc[j]);
            }
        }
    }

    this.sideLoc = tempSideLoc;
    this.sideOrient = tempSideOrient;
    this.edgeLoc = tempEdgeLoc;
    this.edgeOrient = tempEdgeOrient;
    this.cornerLoc = tempCornerLoc;
    this.cornerOrient = tempCornerOrient;

    if (!isQuiet()) {
        fireCubeChanged(new CubeEvent(this, 0, 0, 0));
    }
}

RubiksCube.prototype.clone = function () {
    var that = new RubiksCube();
    that.setTo(this);
    return that;
}

export { RubiksCube };